<script setup lang="ts">
import { computed, ref } from "vue";
import {
    Calendar,
    Search,
    Plus,
    Check,
    Close,
    Delete,
} from "@element-plus/icons-vue";
import { ListItem } from "./types";
import dayjs from "dayjs";
import { Status } from "./data/constants";
import { getStorage, setStorage } from "./utils";

const TodayDate = dayjs().format("YYYY-MM-DD"),
    StorageKey = "TodoList";

const activeDate = ref(""),
    currentDate = computed(() => activeDate.value || TodayDate);

const inputVal = ref("");

const todoList = ref<ListItem[]>([]),
    showList = computed(
        () =>
            todoList.value
                .find((v) => v.date === currentDate.value)
                ?.list.filter(
                    (v) =>
                        activeTab.value === "all" || v.state === activeTab.value
                ) ?? []
    );

const activeTab = ref<Status | "all">("all");

const statusTabs = [
    {
        label: "全部",
        value: "all",
    },
    {
        label: "待处理",
        value: Status.Pending,
    },
    {
        label: "已结束",
        value: Status.Over,
    },
    {
        label: "未完成",
        value: Status.Unfinished,
    },
];

function updateStorageData() {
    setStorage(StorageKey, todoList.value);
}

function addTodo() {
    const target = todoList.value.find((v) => v.date === currentDate.value);
    const itemOption = {
        state: Status.Pending,
        text: inputVal.value,
    };
    if (!target) {
        todoList.value.push({
            date: currentDate.value,
            list: [itemOption],
        });
    } else {
        if (!target.list.some((v) => v.text === inputVal.value)) {
            target.list.push(itemOption);
        }
    }

    updateStorageData();
    inputVal.value = "";
}

function removeTodo(text: string) {
    const currentData = todoList.value.find(
        (v) => v.date === currentDate.value
    )!;
    const index = currentData?.list.findIndex((v) => v.text === text);
    if (~index) {
        currentData.list.splice(index, 1);
    }
    updateStorageData();
}

function changeStatus(
    item: (typeof showList.value)[number],
    state: keyof typeof Status
) {
    const target = todoList.value
        .find((v) => v.date === currentDate.value)
        ?.list.find((v) => v.text === item.text);

    target!.state = Status[state];

    updateStorageData();
}

function init() {
    const data = getStorage(StorageKey);
    todoList.value = data || [];
}

init();
</script>

<template>
    <div class="common-layout">
        <el-container>
            <el-header class="border-b flex items-center justify-between">
                <div class="text-xl font-bold">ToDo List</div>
                <div class="flex items-center justify-between gap-4">
                    <el-input
                        v-model="inputVal"
                        style="width: 360px"
                        clearable
                        placeholder="新增一个待办事项吧"
                        @keyup.enter="addTodo">
                        <template #append>
                            <el-button type="primary" @click="addTodo"
                                >新增</el-button
                            >
                        </template>
                    </el-input>
                </div>
            </el-header>
            <el-main class="flex flex-col">
                <div class="flex-shrink-0"></div>
                <div class="flex-1 flex">
                    <el-tabs
                        v-model="activeTab"
                        tab-position="left"
                        style="height: 200px"
                        class="flex-shrink-0">
                        <el-tab-pane
                            :label="tab.label"
                            :name="tab.value"
                            v-for="tab in statusTabs"></el-tab-pane>
                    </el-tabs>
                    <div
                        class="relative flex-1 space-y-4 border rounded-lg p-4 shadow-sm min-h-[40vh]">
                        <div
                            class="border relative rounded px-4 py-3 hover:shadow"
                            :class="{'hover:bg-blue-100': item.state === Status.Pending}"
                            v-for="item in showList">
                            <div
                                v-show="item.state != Status.Pending"
                                class="absolute top-0 left-0 w-full h-full z-10 opacity-50 flex items-center [&>*]:hover:visible"
                                :class="[
                                    {
                                        ' bg-red-200':
                                            item.state === Status.Unfinished,
                                        'bg-green-200':
                                            item.state === Status.Over,
                                    },
                                ]">
                                <el-popconfirm
                                    title="确认删除？"
                                    @confirm="removeTodo(item.text)">
                                    <template #reference>
                                        <el-button
                                            class="ml-auto mr-4 invisible"
                                            type="danger"
                                            size="small"
                                            :icon="Delete" />
                                    </template>
                                </el-popconfirm>
                            </div>
                            <div class="flex items-center justify-between">
                                <div>{{ item.text }}</div>
                                <div
                                    class="flex gap-2"
                                    :class="{
                                        invisible: item.state != Status.Pending,
                                    }">
                                    <el-button
                                        type="success"
                                        size="small"
                                        plain
                                        :icon="Check"
                                        @click="changeStatus(item, 'Over')" />
                                    <el-button
                                        type="danger"
                                        size="small"
                                        plain
                                        :icon="Close"
                                        @click="
                                            changeStatus(item, 'Unfinished')
                                        " />
                                </div>
                            </div>
                        </div>
                        <el-empty
                            description="暂无数据"
                            v-show="!showList.length" />
                    </div>
                </div>
            </el-main>
        </el-container>
    </div>
</template>

<style scoped></style>
